package thread;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;

/**
 * 文件复制
 */
public class FileCopy extends JFrame implements ActionListener {
    private JTextField tf1, tf2;
    private JProgressBar pb;
    private JButton bt1, bt2, cp;
    private FileInputStream fis;
    private File srcFile;//原文件夹
    private  String mbFile;//目标文件夹

    /**
     * 构造方法
     * 以下17——42行是写界面
     */
    public FileCopy() {
        setTitle("文件复制");
        setSize(800, 500);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLayout(null);
        JLabel label1 = new JLabel("选择文件");
        JLabel label2 = new JLabel("复制到");
        label1.setBounds(100, 50, 100, 25);
        label2.setBounds(100, 100, 100, 25);
        add(label1);add(label2);//Java.util.ArrayList.add()方法实例。add(E e)，将指定的元素添加到此列表的尾部。
        tf1 = new JTextField();
        tf2 = new JTextField();
        tf1.setBounds(200, 50, 300, 25);
        tf2.setBounds(200, 100, 300, 25);
        tf1.setEditable(false);//setselected(false)是设置选项不可用。此处禁止键盘输入源文件地址
        tf2.setEditable(false);//禁止键盘输入文件复制目的地地址
        add(tf1);add(tf2);
        bt1 = new JButton("...");
        bt2 = new JButton("...");
        bt1.setBounds(550, 50, 60, 25);
        bt2.setBounds(550, 100, 60, 25);
        bt1.addActionListener(this);
        bt2.addActionListener(this);
        add(bt1);add(bt2);
        cp = new JButton("复制");
        cp.setBounds(320, 300, 60, 25);
        cp.addActionListener(this);
        add(cp);
        pb = new JProgressBar();
        pb.setStringPainted(true);
        pb.setBounds(150, 175, 400, 25);
        add(pb);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new FileCopy();
            }
        });
    }

    @Override//添加监听
    public void actionPerformed(ActionEvent e) {
        Object o = e.getSource();
        if (o == bt1) {//选择文件
            //JOptionPane.showMessageDialog(this,"选择");//测试用的
            JFileChooser fc = new JFileChooser();
            //fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);//限定只能选择文件夹
            int f = fc.showOpenDialog(this);
            //showSaveDialog(Component parent)弹出一个 "Save File" 文件选择器对话框。f为0代表打开了文件
            if (f == JFileChooser.APPROVE_OPTION) {//APPROVE_OPTION选择确认（yes、ok）后返回该值。
                srcFile= fc.getSelectedFile();
                tf1.setText(srcFile.getPath());
            }
        } else if (o == bt2) {//选择目的文件夹
            //JOptionPane.showMessageDialog(this,"复制到");//测试用的
            JFileChooser fo = new JFileChooser();
            fo.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
            int f1 = fo.showOpenDialog(this);
            if (f1 == JFileChooser.APPROVE_OPTION) {
                mbFile = fo.getSelectedFile().getPath();
                tf2.setText(mbFile);
            }
        } else if (o == cp) {//开始复制
            //JOptionPane.showMessageDialog(this,"复制");//测试用的
            if (srcFile==null||mbFile==null){
                JOptionPane.showMessageDialog(this,"请选择文件");
                return;
            }//先判断选择的是否是文件

            /**
             * 下面的复制和进度条显示运用线程：
             *    用的一个匿名内部类，
             *    如果不采用线程，那么进度条只会从0%跳到100%，且复制按钮在没完成复制是不会弹起来
             */
           new Thread(new Runnable() {
               @Override
               public void run() {//实现run（）方法
                   File file1=new File( mbFile+"\\"+srcFile.getName());//复制到哪里去
                   try {
                       FileInputStream fis = new FileInputStream(srcFile);//实例化输入流
                       FileOutputStream fos=new FileOutputStream(file1);//实例化输出流
                       byte[] tmp=new byte[8192];//数组定义一次读取文件的数值大小
                       int c= fis.read();//判断输入流是否有数据，有输出1，没有输出-1，并存入c中
                       long fsize=srcFile.length();//根据源文件的长度赋给进度条
                       int percent=0;//进度条初始值为0
                       while (c!=-1){//循环
                           fos.write(tmp,0,c);//把存入数组中的数据写入输出流
                           percent=(int) ((1.0-1.0*fis.available()/fsize)*100);//进度条的算法
                           pb.setValue(percent);
                           //System.out.println(percent);
                           c= fis.read(tmp);//循环读取输入流数据
                       }
                       fis.close();fos.close();
                   } catch (FileNotFoundException e1) {
                       e1.printStackTrace();
                   } catch (IOException e1){
                       e1.printStackTrace();
                   }
               }
           }).start();
        }
    }
}

